/**
 * 
 */
package com.maywide.jdp.system.aspect;

import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.jboss.cache.Cache;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import com.maywide.jdp.core.exception.AppException;
import com.maywide.jdp.core.vo.Context;
import com.maywide.jdp.system.annotation.AccessChecked;
import com.maywide.jdp.system.entities.Role;

/**
 * @author luoyang
 */
@Aspect
@Component("accessCheckAspect")
public class AccessCheckAspect {
	private Cache<String, Object> cache = null;

	@Resource(name = "cache")
	public void setCache(Cache<String, Object> cache) {
		this.cache = cache;
	}

	@SuppressWarnings( { "unused", "unchecked" })
	@Order(200)
	@Before(value="execution(public * com.maywide.jdp.system.service.*ServiceImpl.*(..)) and args(..,request,response,session) and @annotation(com.maywide.jdp.system.annotation.AccessChecked) and @annotation(needed)",argNames="needed,request,response,session")
	private void doAccessCheck(JoinPoint jp, AccessChecked needed,
			HttpServletRequest request, HttpServletResponse response,
			HttpSession session) throws Exception {
		if (!needed.value())
			return;
		Context context = (Context) session.getAttribute("context");
		String[] roleIDs = context.getRoleIDs();

		Object target = jp.getTarget();
		String key = jp.getSignature().getName();
		String path = new StringBuffer("/").append(
				jp.getTarget().getClass().getName().replace('.', '/')).append(
				"/").append(key).toString();
		List<Role> roles = (List<Role>) cache.get(path, "role");

		boolean checked = false;
		if (roles != null && !roles.isEmpty() && roleIDs != null
				&& roleIDs.length > 0) {
			int n = roleIDs.length;
			for (int i = 0; i < n; i++) {
				Role role = new Role();
				role.setId(roleIDs[i]);
				if (roles.contains(role)) {
					checked = true;
					break;
				}
			}
		}

		if (!checked)
			throw new AppException("没有访问权限!");
	}
}
